#ifndef __modbus_H
#define __modbus_H

#include "usart_485.h"
#include <string.h>

// Modbus功能码定义
#define MODBUS_READ_COILS                 0x01          //读线圈状态
#define MODBUS_READ_DISCRETE_INPUTS       0x02          //读离散输入状态
#define MODBUS_READ_HOLDING_REGISTERS     0x03          //读保持寄存器
#define MODBUS_READ_INPUT_REGISTERS       0x04          //读输入寄存器
#define MODBUS_WRITE_SINGLE_COIL          0x05          //写单个线圈
#define MODBUS_WRITE_SINGLE_REGISTER      0x06          //写单个寄存器
#define MODBUS_WRITE_MULTIPLE_COILS       0x0F          //写多个线圈
#define MODBUS_WRITE_MULTIPLE_REGISTERS   0x10          //写多个寄存器

// Modbus异常码定义
#define MODBUS_EXCEPTION_ILLEGAL_FUNCTION        0x01       // 非法功能码
#define MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS    0x02       // 非法数据地址
#define MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE      0x03       // 非法数据值
#define MODBUS_EXCEPTION_SLAVE_DEVICE_FAILURE    0x04       // 从站设备故障

// Modbus配置参数
#define MODBUS_RTU_ADDRESS_MIN           0   // 最小从站地址
#define MODBUS_RTU_ADDRESS_MAX           247 // 最大从站地址

// 响应超时时间(ms)
#define MODBUS_RTU_RESPONSE_TIMEOUT      200

// CRC校验宏
#define MODBUS_CRC16_POLYNOMIAL          0xA001             // CRC16多项式
#define MODBUS_CRC16_INIT_VALUE          0xFFFF             // CRC16初始值

//扫描设备参数
#define MODBUS_MAX_DEVICES       32      // 最大支持的设备数量
#define MODBUS_MAX_REGISTERS     128     // 每个设备最大支持的寄存器数量

// 设备数据结构体
typedef struct {
    uint8_t address;            // 设备地址
    uint16_t register_count;    // 读取到的寄存器数量
    uint16_t registers[MODBUS_MAX_REGISTERS]; // 寄存器数据
    uint8_t product_type;       // 产品类型下标
} modbus_device_data_t;


// 设备信息类型枚举
typedef enum {
    INFO_COMM_ADDRESS = 0,  // 通信地址
    INFO_DEVICE_ID,         // 设备ID
    INFO_PROTOCOL_VERSION,  // 通信协议版本号
    INFO_PRODUCT_MODEL,     // 产品型号
    INFO_DEVICE_VERSION,    // 软硬件版本
    INFO_MAX_TYPES          // 信息类型总数
} DeviceInfoType;

// Modbus RTU帧结构
typedef struct {
    uint8_t address;        // 从站地址
    uint8_t function;       // 功能码
    uint8_t data[256];      // 数据域
    uint16_t data_length;   // 数据长度
    uint16_t crc;           // CRC校验值
} modbus_rtu_frame_t;

// Modbus从站回调函数类型
typedef uint8_t (*modbus_callback_t)(uint8_t function, uint16_t address, uint16_t quantity, uint16_t *values);

// Modbus主站(客户端)函数
bool modbus_rtu_master_send_request(uint8_t slave_address, uint8_t function, 
                                   uint16_t start_address, uint16_t quantity, 
                                   uint16_t *data, uint16_t data_length);
bool modbus_rtu_master_read_response(uint8_t *response, uint16_t *response_length);


// 通用Modbus函数
uint16_t modbus_rtu_crc16(uint8_t *data, uint16_t length);
bool modbus_rtu_validate_frame(modbus_rtu_frame_t *frame);
void modbus_rtu_parse_frame(uint8_t *data, uint16_t length, modbus_rtu_frame_t *frame);
uint16_t modbus_rtu_build_frame(uint8_t address, uint8_t function, 
                               uint8_t *data, uint16_t data_length, 
                               uint8_t *frame);


//扫描从设备
bool modbus_scan_and_read_devices(uint8_t start_addr, uint8_t end_addr, 
                                modbus_device_data_t *device_data, 
                                uint8_t max_devices, 
                                uint8_t *found_devices);

#endif